package com.h3c.nem.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eos.common.util.IdWorker;
import com.h3c.nem.cache.TbOfferWorkerCache;
import com.h3c.nem.config.properties.TbOfferWorkerProperties;
import com.h3c.nem.dto.TbOfferStudyDTO;
import com.h3c.nem.dto.TbOfferStudySaveDTO;
import com.h3c.nem.entity.TbOfferStudy;
import com.h3c.nem.entity.TbOfferWorker;
import com.h3c.nem.enums.EducationLevelEnum;
import com.h3c.nem.mapper.TbOfferStudyMapper;
import com.h3c.nem.mapstruct.TbOfferStudyMapstruct;
import com.h3c.nem.service.ITbOfferStudyService;
import com.h3c.nem.service.ITbOfferWorkerService;
import com.h3c.nem.utils.AppBusinessException;
import com.h3c.nem.utils.CommonUtil;
import com.h3c.nem.vo.TbOfferStudyVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 学历信息实现类
 *
 * @author chenyifan
 * @since 2022-06-06 11:42:52
 */
@Service
public class TbOfferStudyServiceImpl extends ServiceImpl<TbOfferStudyMapper, TbOfferStudy> implements ITbOfferStudyService {

    @Resource(name = "baseOfferWorker")
    private TbOfferWorkerProperties workerProperties;

    @Resource
    private ITbOfferWorkerService offerWorkerService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveStudyInfo(TbOfferStudySaveDTO studySaveDTO) {
        //去重判断是否有重复
        ArrayList<TbOfferStudyDTO> tempList = studySaveDTO.getStudySaveDTOS().stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(
                                () -> new TreeSet<>(Comparator
                                        .comparing(TbOfferStudyDTO::getBeginDate)
                                        .thenComparing(TbOfferStudyDTO::getGrantDate)
                                        .thenComparing(TbOfferStudyDTO::getCollegeName)
                                        .thenComparing(TbOfferStudyDTO::getMajorName))), ArrayList::new));
        if (tempList.size() != studySaveDTO.getStudySaveDTOS().size()) {
            throw new AppBusinessException("检测到您的学历信息存在重复填写情况，请勿重复录入，谢谢！");
        }
        //判断截止时间是否小于开始时间
        for (TbOfferStudyDTO studyDTO : studySaveDTO.getStudySaveDTOS()) {
            if (DateUtil.compare(studyDTO.getBeginDate(), studyDTO.getEndDate()) > 0) {
                throw new AppBusinessException("毕业院校为:" + studyDTO.getCollegeName() + "的信息开始时间应早于毕业日期");
            }
        }
        //处理数据
        studySaveDTO.getStudySaveDTOS().stream()
                .forEach(s -> s.setIsFirstStudy(false).setIsHighestEducation(false).setIsHighestDegree(false));
        //1.过滤大专以下的学历
        List<TbOfferStudyDTO> realStudySaveDTO = studySaveDTO.getStudySaveDTOS().stream()
                .filter(s -> s.getEducation().getSort() >= EducationLevelEnum.COLLEGE.getSort())
                .collect(Collectors.toList());
        if (realStudySaveDTO.size() == 0) {
            throw new AppBusinessException("无大专以上学历，请联系人工处理");
        }
        //2.根据学历和时间选出最高学历、最高学位          第一学历
        Comparator<TbOfferStudyDTO> compBySort = Comparator.comparing(s -> s.getEducation().getSort());
        Comparator<TbOfferStudyDTO> compByTime = Comparator.comparing(TbOfferStudyDTO::getGrantDate);
        realStudySaveDTO = realStudySaveDTO.stream()
                .sorted(compBySort.thenComparing(compByTime))
                .collect(Collectors.toList());
        if (realStudySaveDTO.size() == 1) {
            realStudySaveDTO.get(0)
                    .setIsFirstStudy(true)
                    .setIsHighestEducation(true)
                    .setIsHighestDegree(true);
        } else {
            realStudySaveDTO.get(0)
                    .setIsFirstStudy(true)
                    .setIsHighestEducation(false)
                    .setIsHighestDegree(false);
            realStudySaveDTO.get(realStudySaveDTO.size() - 1)
                    .setIsFirstStudy(false)
                    .setIsHighestDegree(true)
                    .setIsHighestEducation(true);
        }
        TbOfferWorker offerWorker = offerWorkerService.getById(CommonUtil.getActivUser().getUserId());
        List<TbOfferStudyDTO> lowStudyList = studySaveDTO.getStudySaveDTOS().stream()
                .filter(s -> s.getEducation().getSort() < EducationLevelEnum.COLLEGE.getSort())
                .collect(Collectors.toList());
        realStudySaveDTO.addAll(lowStudyList);

        if (workerProperties.getIsJudgeEducation()) {
            judgeStudyInfo(realStudySaveDTO);
        }
        if(offerWorker.getInType().equals("社会招聘") && DateUtil.compare(realStudySaveDTO.get(0).getEndDate(),studySaveDTO.getJoinJobTime()) > 0){
            throw new AppBusinessException("参加工作日期需晚于第一份学历的毕业日期，请您核实修改");
        }
        offerWorkerService.update(null, new LambdaUpdateWrapper<TbOfferWorker>()
                .set(TbOfferWorker::getFirstWorkDate, studySaveDTO.getJoinJobTime())
                .eq(TbOfferWorker::getWorkerId, CommonUtil.getActivUser().getUserId())
        );
        remove(new QueryWrapper<TbOfferStudy>().lambda()
                .eq(TbOfferStudy::getWorkerId, CommonUtil.getActivUser().getUserId())
        );
        List<TbOfferStudy> tbOfferStudies = TbOfferStudyMapstruct.INSTANCE.DTOList2EntityList(studySaveDTO.getStudySaveDTOS());
        tbOfferStudies.forEach(s -> s.setStudyId(IdWorker.nextId() + "").setUpdateTime(new Date()).setWorkerId(CommonUtil.getActivUser().getUserId()));
        saveBatch(tbOfferStudies);
        TbOfferWorkerCache.updateFillStatus(CommonUtil.getActivUser().getUserId(), TbOfferWorkerCache.STUDY);
    }

    @Override
    public Boolean judgeStudyInfo(List<TbOfferStudyDTO> studyDTOS) {
        //第一学历有且仅有一条
        List<TbOfferStudyDTO> firstStudyList = studyDTOS.stream().filter(TbOfferStudyDTO::getIsFirstStudy).collect(Collectors.toList());
        if (firstStudyList.size() != 1) {
            throw new AppBusinessException("第一学历应有且仅有一条");
        }
        //最高学历有且仅有一条
        List<TbOfferStudyDTO> highEducationList = studyDTOS.stream().filter(TbOfferStudyDTO::getIsHighestEducation).collect(Collectors.toList());
        if (highEducationList.size() != 1) {
            throw new AppBusinessException("最高学历应有且仅有一条");
        }
        //最高学历的学历应该比第一学历高
        if (highEducationList.get(0).getEducation().getSort().compareTo(firstStudyList.get(0).getEducation().getSort()) < 0) {
            throw new AppBusinessException("最高学历的学历应比第一学历高");
        }
        //当有硕士及以上学历时，第一学历不能勾选在硕士及以上学历
        int moreThanMaster = (int) studyDTOS.stream().filter(s -> EducationLevelEnum.judgeIfMoreThanMaster(s.getEducation())).count();
        if (moreThanMaster > 0) {
            if (EducationLevelEnum.judgeIfMoreThanMaster(firstStudyList.get(0).getEducation())) {
                throw new AppBusinessException("学历信息不完整，请您补充硕士/博士之前的学历");
            }
        }
        return true;
    }

    @Override
    public Map<String, Object> showStudyInfo() {
        HashMap<String, Object> result = new HashMap<>(2);
        List<TbOfferStudy> studyList = list(new QueryWrapper<TbOfferStudy>().lambda()
                .eq(TbOfferStudy::getWorkerId, CommonUtil.getActivUser().getUserId())
        );
        result.put("studyInfos", TbOfferStudyMapstruct.INSTANCE.entityList2VoList(studyList));
        result.put("joinJobTime", DateUtil.format(offerWorkerService.getById(CommonUtil.getActivUser().getUserId()).getFirstWorkDate(),
                "yyyy-MM-dd"));
        return result;
    }

    @Override
    public List<TbOfferStudyVO> getStudyInfoByWorkerId(String workerId) {
        return getStudyInfoByWorkerId(workerId, false);
    }

    @Override
    public List<TbOfferStudyVO> getStudyInfoByWorkerId(String workerId, Boolean isFirstStudy) {
        LambdaQueryWrapper<TbOfferStudy> queryWrapper = new QueryWrapper<TbOfferStudy>().lambda();
        queryWrapper.eq(TbOfferStudy::getWorkerId, workerId);
        if (isFirstStudy) {
            queryWrapper.eq(TbOfferStudy::getIsHighestEducation, true);
        }
        List<TbOfferStudy> studyList = list(queryWrapper);
        return TbOfferStudyMapstruct.INSTANCE.entityList2VoList(studyList);
    }
}

